using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace RedirectRequest.Features.Redirection_Handler
{
    /// <summary>
    ///     This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
    /// </summary>
    /// <remarks>
    ///     The GUID attached to this class may be used during packaging and should not be modified.
    /// </remarks>
    [Guid("3c3868cd-9b44-4a2e-a1e8-9ed8f13bfad4")]
    public class Redirection_HandlerEventReceiver : SPFeatureReceiver
    {
        private const string CWebConfigModificationOwner = "redirector";

        private readonly SPWebConfigModification spWebConfigModification = new SPWebConfigModification
            {
                // The owner of the web.config modification, useful for removing a 
                // group of modifications
                Owner = CWebConfigModificationOwner,
                // Make sure that the name is a unique XPath selector for the element 
                // we are adding. This name is used for removing the element
                Name = "add[@name='RedirectModule']",
                // We are going to add a new XML node to web.config
                Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
                // The XPath to the location of the parent node in web.config
                Path = "configuration/system.webServer/modules",
                // Sequence is important if there are multiple equal nodes that 
                // can't be identified with an XPath expression
                Sequence = 0,
                // The XML to insert as child node, make sure that used names match the Name selector
                Value =
                    "<add name='RedirectModule' type='Redirection.RedirectionModule, Redirection, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3b58b7fcb1fcf3cf' />"
            };

        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            var webApp = properties.Feature.Parent as SPWebApplication;
            if (webApp != null)
            {
                AddWebConfigModifications(webApp, spWebConfigModification);
            }
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            var webApp = properties.Feature.Parent as SPWebApplication;
            if (webApp != null)
            {
                RemoveWebConfigModificationsByOwner(webApp, CWebConfigModificationOwner);
            }
        }

        private void AddWebConfigModifications(SPWebApplication webApp, SPWebConfigModification modification)
        {
            Debugger.Break();

            webApp.WebConfigModifications.Insert(0, modification);

            // Commit modification additions to the specified web application
            webApp.Update();

            // Push modifications through the farm
            SPFarm.Local.Services.GetValue<SPWebService>(webApp.Parent.Id).ApplyWebConfigModifications();
        }

        /// <summary>
        ///     Remove modifications from the web application
        /// </summary>
        /// <param name="webApp">The web application to remove the modifications from</param>
        /// <param name="owner" Remove all modifications that belong to the owner></param>
        private void RemoveWebConfigModificationsByOwner(SPWebApplication webApp, string owner)
        {
            Collection<SPWebConfigModification> modificationCollection = webApp.WebConfigModifications;
            var removeCollection = new Collection<SPWebConfigModification>();

            int count = modificationCollection.Count;
            for (int i = 0; i < count; i++)
            {
                SPWebConfigModification modification = modificationCollection[i];
                if (modification.Owner == owner)
                {
                    // collect modifications to delete
                    removeCollection.Add(modification);
                }
            }

            // now delete the modifications from the web application
            if (removeCollection.Count > 0)
            {
                foreach (SPWebConfigModification modificationItem in removeCollection)
                {
                    webApp.WebConfigModifications.Remove(modificationItem);
                }

                // Commit modification removals to the specified web application
                webApp.Update();

                // Push modifications through the farm
                SPFarm.Local.Services.GetValue<SPWebService>(webApp.Parent.Id).ApplyWebConfigModifications();
            }
        }
    }
}